/*APPLY:
	PUSH(FP);
	MOV(FP,SP);


	PUSH(R1);
	PUSH(R2);
	PUSH(R3);

	MOV(R0,FPARG(3));
PARAMS_LOOP:
	CMP(R0,2); //COMPARE WITH NIL
	JUMP_EQ(END_PARAMS);


	PUSH(INDD(R0,1));
	MOV(R0,INDD(R0,2));
	JUMP(PARAMS_LOOP);

END_PARAMS:
	MOV(R1,-1);
	MOV(R2,SP);
	SUB(R2,FP);
	DECR(R2);

REVERSE_LOOP:
	CMP(R1,R2);
	JUMP_LE(END_REV);

	MOV(R3,STARG(R1));
	MOV(STARG(R1),STARG(R2));
	MOV(STARG(R2),R3);
	DECR(R1);
	INCR(R2);
	JUMP(REVERSE_LOOP);


END_REV:
	MOV(R1,SP);
	SUB(R1,FP);
	SUB(R1,3);
	PUSH(R1);
	MOV(R2,FPARG(2));
	PUSH(INDD(R2,1));
	CALLA(INDD(R2,2));
	DROP(2);
	DROP(R1);


	POP(R3);
	POP(R2);
	POP(R1);
	POP(FP);
	RETURN;


*/

#define SPARG(n) (STACK(SP-(n)))
APPLY:
	PUSH(FP);
	MOV(FP,SP);


	PUSH(R1);
	PUSH(R2);
	PUSH(R3);
	MOV(R1,0); //init counter
	MOV(R0,FPARG(3)); //R0 = arg list
	PUSH(T_FRAME_END); //magic number
PARAMS_LOOP:
	CMP(R0,2); //COMPARE WITH NIL
	JUMP_EQ(END_PARAMS);
	PUSH(INDD(R0,1));
	INCR(R1);
	MOV(R0,INDD(R0,2));
	JUMP(PARAMS_LOOP);

END_PARAMS:
	MOV(R2,R1);
	MOV(R3,1);

APPLY_REV_LOOP:
	CMP(R2,R3);
	JUMP_LE(END_APPLY_REV_LOOP);
	MOV(R0,SPARG(R3));
	MOV(SPARG(R3),SPARG(R2));
	MOV(SPARG(R2),R0);
	INCR(R3);
	DECR(R2);
	JUMP(APPLY_REV_LOOP);

END_APPLY_REV_LOOP:
	PUSH(R1);
	PUSH(INDD(FPARG(2),1));
	CALLA(INDD(FPARG(2),2));
	DROP(R1+2+1);
	POP(R3);
	POP(R2);
	POP(R1);
	POP(FP);
	RETURN;


